//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "logIn.h"
#include "selection.h"
#include "STUNELoan.h"
#include "LoanShop.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
TForm_Loan *Form_Loan;
LoanShop* loanShop = NULL; // pointer for the shop object
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// ADO database functions

// check the shop
bool checkShop(AnsiString shopId, AnsiString &shopName)
{
	shopName = "stune loan";
	return true;
	//**********

	AnsiString query = "select shop_name from shop where shop_id = "+shopId; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->Open(); // open the query
		if (Form_Loan->ADOQueryDB->Eof) // check if there is a result
		{
			return false;	// there were no rows; no result
		}
		shopName = Form_Loan->ADOQueryDB->FieldByName("shop_name")->AsString; // store the result
		Form_Loan->ADOQueryDB->Close(); // close the query
		return true; // query was succesfull
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
}

// get the stock from the database
bool getLoanStock(AnsiString shopId)
{
	loanShop->addArticle1(1, "Kingston USB-3.0", 350, "Cables", 1.5, 3.0);
	loanShop->addArticle1(2, "Universal Charger", 190, "Charger", 2.75, 7.0);
	loanShop->addArticle1(3, "Canon X34564", 50, "Camera", 8.90, 50.0);
	return true;
	//**********

	AnsiString nm, kd; int id, qt; double pr, dp; // temp variables

	AnsiString query = "select article_id, name, quantity, kind, price, deposit from articles join articles_in_shop where shop_id = "+shopId; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->Open(); // open the query
		if (Form_Loan->ADOQueryDB->Eof) // check if there is a result
		{
			return false;	// there were no rows; no result
		}
		while (!Form_Loan->ADOQueryDB->Eof) // loop through all the rows; all results
		{
			id = Form_Loan->ADOQueryDB->FieldByName("article_id")->AsInteger; // store the result
			nm = Form_Loan->ADOQueryDB->FieldByName("name")->AsString; // store the result
			qt = Form_Loan->ADOQueryDB->FieldByName("quantity")->AsInteger; // store the result
			kd = Form_Loan->ADOQueryDB->FieldByName("kind")->AsString; // store the result
			pr = Form_Loan->ADOQueryDB->FieldByName("price")->AsFloat; // store the result
			dp = Form_Loan->ADOQueryDB->FieldByName("deposit")->AsFloat; // store the result
			loanShop->addArticle1(id, nm, qt, kd, pr, dp); // add the article to the shop
			Form_Loan->ADOQueryDB->Next();// go to next row
        }
		Form_Loan->ADOQueryDB->Close(); // close the query
		return true; // query was succesfull
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
}

// get the balance of the guest
bool getBalance(AnsiString guestId, double &balance)
{
	if (guestId == "1234")
	{
		balance  = 45.0;
		return true;
	}
	return false;
	//*****

	AnsiString query = "select balance from guests where guest_id = "+guestId; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->Open(); // open the query
		if (Form_Loan->ADOQueryDB->Eof) // check if there is a result
		{
			return false;	// there were no rows; no result
		}
		balance = Form_Loan->ADOQueryDB->FieldByName("balance")->AsFloat; // store the result
		Form_Loan->ADOQueryDB->Close(); // close the query
		return true; // query was succesfull
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
}

// decrease the balance of the guest
bool decreaseBalance(AnsiString guestId, double total)
{
	return true;
	//*****

	AnsiString query = "update guests set balance = balance-"+AnsiString(total)+" where guest_id = "+guestId; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->ExecSQL(); // do the update query
		return true; // query was succesfull
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
}

// *** new functions that work for loan:
// decrease the stock of the shop
bool decreaseLoanStock(int id, int qt)
{
	return true;
	//***
	
	AnsiString query = "update articles_in_shop set quantity = quantity-"+AnsiString(qt)+" where article_id = "+AnsiString(id)+" and shop_id = "+loanShop->getID1(); // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->ExecSQL(); // do the update query
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
	return true; // query was succesfull
}

// increase the stock of the shop
bool increaseLoanStock(int id, int qt)
{
	return true;
	//***

	AnsiString query = "update articles_in_shop set quantity = quantity+"+AnsiString(qt)+" where article_id = "+AnsiString(id)+" and shop_id = "+loanShop->getID1(); // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->ExecSQL(); // do the update query
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
	return true; // query was succesfull
}

// get all loans of the guest
bool getGuestLoans(AnsiString gid)
{
	if (loanShop->insertGuestLoanToPurchase1(1, 1) == false)
	{
        return false;
    }
	return true;
	//***
	
	int id, qt;
	AnsiString query = "select article_id, quantity from articles loans_of_guest where guest_id = "+gid; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->Open(); // open the query
		if (Form_Loan->ADOQueryDB->Eof) // check if there is a result
		{
			return false;	// there were no rows; no result
		}
		while (!Form_Loan->ADOQueryDB->Eof) // loop through all the rows; all results
		{
			id = Form_Loan->ADOQueryDB->FieldByName("article_id")->AsInteger; // store the result
			qt = Form_Loan->ADOQueryDB->FieldByName("quantity")->AsInteger; // store the result
			loanShop->insertGuestLoanToPurchase1(id, qt); // add the article to the shop purchase
			Form_Loan->ADOQueryDB->Next();// go to next row
        }
		Form_Loan->ADOQueryDB->Close(); // close the query
		return true; // query was succesfull
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
}
// register a loan article to a guest
bool addLoanToUser(AnsiString gid, int id, int qt)
{
	return true;
	//***
	
	AnsiString query = "insert"; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->ExecSQL(); // do the update query
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
	return true; // query was succesfull
}

// unregister a loan from a guest
bool removeLoanFromUser(AnsiString gid, int id, int qt)
{
	return true;
	//***
	
	AnsiString query = "remove"; // prepare query
	Form_Loan->ADOQueryDB->SQL->Clear(); // clear the previous ado query
	Form_Loan->ADOQueryDB->SQL->Add(query); // add the query to the ado
	try // try to query the database
	{
		Form_Loan->ADOQueryDB->ExecSQL(); // do the update query
	}
	catch  (Exception &err)
	{
		return false; // there was an error
	}
	return true; // query was succesfull
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
AnsiString padRight(AnsiString str, int len)
{
	if (str.Length() < len)
	{
		return str+AnsiString().StringOfChar(' ', len-str.Length());
	}
	else
	{
		return str+" ";
	}
}

void updateInfo()
{
	// show some info
		// check the total...
	if (!Form_Loan->edtQuantity->Text.IsEmpty())
	{
		if (Form_Loan->ListOfStocksLoan->ItemIndex != -1)
		{
			if (Form_Loan->edtQuantity->Text.ToInt() > loanShop->getArticleAtIndex1(Form_Loan->ListOfStocksLoan->ItemIndex)->getNrOfItems1())
			{
				Form_Loan->edtQuantity->Text = AnsiString(loanShop->getArticleAtIndex1(Form_Loan->ListOfStocksLoan->ItemIndex)->getNrOfItems1());
			}
		}
		else if (Form_Loan->ListPurchase->ItemIndex != -1)
		{
			if (Form_Loan->edtQuantity->Text.ToInt() > loanShop->getPurchaseQtAtIndex1(Form_Loan->ListPurchase->ItemIndex))
			{
				Form_Loan->edtQuantity->Text = AnsiString(loanShop->getPurchaseQtAtIndex1(Form_Loan->ListPurchase->ItemIndex));
			}
		}
	}
	int artId;
	
	if (Form_Loan->ListOfStocksLoan->ItemIndex != -1)
	{
		artId = Form_Loan->ListOfStocksLoan->ItemIndex;
		Form_Loan->lblSelectedItem->Caption = loanShop->getArticleAtIndex1(artId)->getName1();

		if (!Form_Loan->edtQuantity->Text.IsEmpty())
		{
			Form_Loan->lblFee->Caption = AnsiString().FormatFloat("0.00", Form_Loan->edtQuantity->Text.ToInt()*loanShop->getArticleAtIndex1(artId)->getPrice1());
			Form_Loan->lblDeposit->Caption = AnsiString().FormatFloat("0.00", Form_Loan->edtQuantity->Text.ToInt()*loanShop->getArticleAtIndex1(artId)->getDeposit1());
			Form_Loan->lblTotal->Caption = AnsiString().FormatFloat("0.00", Form_Loan->lblFee->Caption.ToDouble()+Form_Loan->lblDeposit->Caption.ToDouble());
		}
		else
		{
			Form_Loan->lblFee->Caption = "0.00";
			Form_Loan->lblDeposit->Caption = "0.00";
			Form_Loan->lblTotal->Caption = "0.00";
        }
	}
	else if (Form_Loan->ListPurchase->ItemIndex != -1)
	{
		int itemid = loanShop->getPurchaseIdAtIndex1(Form_Loan->ListPurchase->ItemIndex);
		for (int i = 0; i < loanShop->getNrOfArticles1(); i++)
		{
			if (loanShop->getArticleAtIndex1(i)->getArticleID1() == itemid)
			{
				artId = i;
				break;
			}
		}
		Form_Loan->lblSelectedItem->Caption = loanShop->getArticleAtIndex1(artId)->getName1();

		if (!Form_Loan->edtQuantity->Text.IsEmpty())
		{
			Form_Loan->lblFee->Caption = "0.00";
			Form_Loan->lblDeposit->Caption = AnsiString().FormatFloat("0.00", -Form_Loan->edtQuantity->Text.ToInt()*loanShop->getArticleAtIndex1(artId)->getDeposit1());
			Form_Loan->lblTotal->Caption = AnsiString().FormatFloat("0.00", Form_Loan->lblFee->Caption.ToDouble()+Form_Loan->lblDeposit->Caption.ToDouble());
		}
		else
		{
			Form_Loan->lblFee->Caption = "0.00";
			Form_Loan->lblDeposit->Caption = "0.00";
			Form_Loan->lblTotal->Caption = "0.00";
        }
	}
	else
	{
		Form_Loan->lblSelectedItem->Caption = "<none-selected>";
		Form_Loan->lblFee->Caption = "0.00";
		Form_Loan->lblDeposit->Caption = "0.00";
		Form_Loan->lblTotal->Caption = "0.00";
    }
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// this function shows all articles in the listbox ListOfStock
void showAllArticles()
{
	Form_Loan->ListOfStocksLoan->Clear();		// clear the listbox
	// show all the articles
	for (int index = 0; index < loanShop->getNrOfArticles1(); index++)
	{
			// Show the content of article in listbox.
			Form_Loan->ListOfStocksLoan->Items->Add(loanShop->getArticleAtIndex1(index)->asAString1());
	}
}
//---------------------------------------------------------------------------
void showAllPurchases()
{
	Form_Loan->ListPurchase->Clear();		// clear the listbox
	// show all the purchases
	for (int index = 0; index < loanShop->getNrOfPurchases1(); index++)
	{
			// Show the content of purchase in listbox.
			int qt = loanShop->getPurchaseQtAtIndex1(index);			// get the quantity
			AnsiString temp = padRight(AnsiString(qt)+"x", 6);              // show quantity
			temp += padRight(loanShop->getPurchaseAtIndex1(index)->getName1(), 20); // show name
			temp += AnsiString().FormatFloat("0.00", loanShop->getPurchaseAtIndex1(index)->getDeposit1()*qt); // show total price
			Form_Loan->ListPurchase->Items->Add(temp); 			// show the info in listbox
	}
}
//---------------------------------------------------------------------------
// this function shows a error to the user
void ShowError(AnsiString error)
{
    ShowMessage(error);
}
//---------------------------------------------------------------------------
__fastcall TForm_Loan::TForm_Loan(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::btnReturnClick(TObject *Sender)
{
	int index = this->ListPurchase->ItemIndex;
	if (index != -1)   // if purchase item selected
	{
		if (!this->edtQuantity->Text.IsEmpty())// check edit quantity is not empty
		{
			/*
			   1. get purchase id
			   2. remove the purchase
			*/
			int id = loanShop->getPurchaseAtIndex1(index)->getArticleID1();	// get purchase id
			loanShop->unsoldSome1(id, this->edtQuantity->Text.ToInt());

			// get the deposit of this item
			double deposit = loanShop->getPurchaseAtIndex1(index)->getDeposit1();

			// update the database
			// 1) increase loanstock, 2) remove loan from user, 3) increase balance
			if (this->edtQuantity->Text.ToInt() > loanShop->getPurchaseQtAtIndex1(index))
			{
				 increaseLoanStock(id, loanShop->getPurchaseQtAtIndex1(index));
				 decreaseBalance(this->edtGuestId->Text, -(deposit*loanShop->getPurchaseQtAtIndex1(index)));
			}
			else
			{
				 increaseLoanStock(id, this->edtQuantity->Text.ToInt());
				 decreaseBalance(this->edtGuestId->Text, -(deposit*this->edtQuantity->Text.ToInt()));
            }
			removeLoanFromUser(this->edtGuestId->Text, id, this->edtQuantity->Text.ToInt());

			// refresh listbox
			showAllArticles();
			showAllPurchases();

			// reupdate the info
			updateInfo();
		}
		else    // quantity is empty
		{
			ShowError("Please enter a quantity!"); //show error message
		}
	}
	else // current loan not selected
	{
		ShowError("Please select a current loan!");
	}
}

//---------------------------------------------------------------------------

void __fastcall TForm_Loan::btnBrokenClick(TObject *Sender)
{
	int index = this->ListPurchase->ItemIndex;
	if (index != -1)   // if purchase item selected
	{
		if (!this->edtQuantity->Text.IsEmpty())// check edit quantity is not empty
		{
			/*
			   1. get purchase id
			   2. remove the purchase
			*/
			int id = loanShop->getPurchaseAtIndex1(index)->getArticleID1();	// get purchase id

			// update the database
			// 1) remove loan from user (broken)
			removeLoanFromUser(this->edtGuestId->Text, id, this->edtQuantity->Text.ToInt());

			// update the shop
			loanShop->unsoldBroken1(id, this->edtQuantity->Text.ToInt());

			// refresh listbox
			showAllPurchases();

			// reupdate the info
			updateInfo();
		}
		else    // quantity is empty
		{
			ShowError("Please enter a quantity!"); //show error message
		}
	}
	else // current loan not selected
	{
		ShowError("Please select a current loan!");
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::btnOpenGuestAccountClick(TObject *Sender)
{
	/*
	   1. get all the current loans of the user
	*/

	if (!this->edtGuestId->Text.IsEmpty())   // guest id is not empty
		{
			double temp;
			if (getBalance(this->edtGuestId->Text, temp) == true)   // check if user exists
			{
				// get the loans
				if (getGuestLoans(this->edtGuestId->Text) == false)
				this->edtGuestId->Enabled = false;  // dont let the id change

				// show loans
				showAllPurchases();

				// enable actions
				this->edtQuantity->Enabled = true;
				this->btnBorrow->Enabled = true;
				this->btnReturn->Enabled = true;
				this->btnBroken->Enabled = true;
				this->ListPurchase->Enabled = true;

				// dont let us change the id
				this->btnOpenAccount->Enabled = false;
			}
			else
			{
                ShowMessage("Guest ID not found!");
            }
		}
		else // guest id is empty
		{
			ShowMessage("Please enter a Guest ID!");
		}
	}

//---------------------------------------------------------------------------

void __fastcall TForm_Loan::edtQuantityKeyPress(TObject *Sender, char &Key)
{
	// only allow 0-9 and backspace, also make sure value is higher than 0
	if (!((Key >= '0' && Key <= '9') || Key == VK_BACK))
	{
    	Key = 0;
	}
	else if (this->edtQuantity->Text.IsEmpty() && Key == '0')
	{
    	Key = 0;
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::btnCancelClick(TObject *Sender)
{
	// clear the purchase
	this->ListPurchase->Clear();
	loanShop->clearAllPuchases1();

	// clear some labels and edit boxes
	this->edtQuantity->Clear();			   // clear the quantity
	this->edtGuestId->Clear();			   // clear the guest id
	this->lblFee->Caption = "0.00";		   // reset the fee label
	this->lblDeposit->Caption = "0.00";    // reset the deposit label
	this->lblTotal->Caption = "0.00";	   // reset the total label
	this->lblSelectedItem->Caption = "<none-selected>";

	this->edtGuestId->Enabled = true;
	this->btnOpenAccount->Enabled = true;

	// disable actions
	this->edtQuantity->Enabled = false;
	this->btnBorrow->Enabled = false;
	this->btnReturn->Enabled = false;
	this->btnBroken->Enabled = false;
	this->ListPurchase->Enabled = false;

	// clear selection
	this->ListOfStocksLoan->ClearSelection();
}
//---------------------------------------------------------------------------
void __fastcall TForm_Loan::btnSortNameClick(TObject *Sender)
{
	// check if shop is created
	if (loanShop != NULL) {
    	// sort the artiles by name
		loanShop->sortAllArticlesByName1();
	}
	showAllArticles(); 		// next we show the articles
}
//---------------------------------------------------------------------------
void __fastcall TForm_Loan::btnSortPriceClick(TObject *Sender)
{
	// check if shop is created
	if (loanShop != NULL) {
		// sort the artiles by price
		loanShop->sortAllArticlesBySalesValue1();
	}
	showAllArticles(); 		// next we show the articles
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::btnSortKindClick(TObject *Sender)
{
	// check if shop is created
	if (loanShop != NULL) {
		// sort the artiles by kind
		loanShop->sortAllArticlesByKind1();
	}
	showAllArticles(); 		// next we show the articles
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::ListOfStocksLoanClick(TObject *Sender)
{
	// unselect the other list
	this->ListPurchase->ClearSelection();

	// show some info
	updateInfo();
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::ListPurchaseClick(TObject *Sender)
{
	// unselect the other list
	this->ListOfStocksLoan->ClearSelection();

	// show some info
	updateInfo();
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::edtQuantityClick(TObject *Sender)
{
	this->edtQuantity->Text = "";
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::edtQuantityChange(TObject *Sender)
{
	// update the label.
	updateInfo();	
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::FormClose(TObject *Sender, TCloseAction &Action)
{
  selectionForm->Close();
 logInForm->Close();	
}
//---------------------------------------------------------------------------

void __fastcall TForm_Loan::Button1Click(TObject *Sender)
{
  this->Visible=false;
  selectionForm->Visible=true;
}
//---------------------------------------------------------------------------


void __fastcall TForm_Loan::Button2Click(TObject *Sender)
{
	    	/*
	   1. create a shop or if the shop is already created, delete the shop.
	   2. when shop created, make the editbox become disabled and change
		  this button to close shop.
	   3. when the shop is deleted, make the editbox become enabled and change
		  this button to open shop.
	*/

	if (loanShop == NULL) // if there is no shop
	{
		if (!this->edtShopID->Text.IsEmpty()) // check shop name is not empty
		{
			AnsiString tempName = "";
			if (checkShop(this->edtShopID->Text, tempName))
			{
				loanShop = new LoanShop(this->edtShopID->Text, tempName); //create a new shop

				this->Button2->Caption = "Close Shop"; //change the button text
				this->edtShopID->Text = tempName;  // show the name instead of id
				this->edtShopID->Enabled = false;  // disable the edit box

				getLoanStock(loanShop->getID1());	   	   // get the stock
				loanShop->sortAllArticlesByName1();// sort the stock by name first
				showAllArticles(); 		// next we show the articles

				// enable actions
				this->btnCancel->Enabled = true;
				this->Button2->Enabled = true;
				this->edtGuestId->Enabled = true;
				this->btnSortKind->Enabled = true;
				this->btnSortName->Enabled = true;
				this->btnSortPrice->Enabled = true;
				this->ListOfStocksLoan->Enabled = true;
			}
			else
			{
				ShowMessage("Shop ID not found!");
			}
		}
		else // is shop name empty show a error message
		{
			ShowError("Please type a shop name!");
		}
	}
	else // shop exists
	{
		delete loanShop;         //delete the shop
		loanShop = NULL;         //make the pointer equals null
		this->Button2->Caption = "Open Shop";  // change the button text
		this->edtShopID->Enabled = true;       // enable the edit box
		this->edtShopID->Clear();              // clear edit box
		this->ListOfStocksLoan->Clear();   		   // clear the stock list
		this->ListPurchase->Clear();           // clear the purchase list
		this->edtQuantity->Clear();			   // clear the quantity
		this->edtGuestId->Clear();			   // clear the guest id
		this->lblFee->Caption = "0.00";		   // reset the fee label
		this->lblDeposit->Caption = "0.00";    // reset the deposit label
		this->lblTotal->Caption = "0.00";	   // reset the total label
		this->lblSelectedItem->Caption = "<none-selected>";

		// disable actions
		this->edtGuestId->Enabled = false;
		this->btnSortName->Enabled = false;
		this->btnSortPrice->Enabled = false;
		this->edtQuantity->Enabled = false;
		this->btnBorrow->Enabled = false;
		this->btnReturn->Enabled = false;
		this->btnBroken->Enabled = false;
		this->btnCancel->Enabled = false;
		this->btnOpenAccount->Enabled = false;
		this->edtGuestId->Enabled = true;
		this->ListOfStocksLoan->Enabled = false;
		this->ListPurchase->Enabled = false;

		this->btnSortKind->Enabled = false;
		this->btnSortName->Enabled = false;
		this->btnSortPrice->Enabled = false;
	}
}
//---------------------------------------------------------------------------

